﻿namespace HuwmanCode.ComponentModel

open System
open System.Diagnostics
open System.Runtime.CompilerServices
open System.ComponentModel
open HuwmanCode

[<AutoOpen>]
[<Extension>]
module INotifyPropertyChangedExtension =
    [<Extension>]
    let OnPropertyChanged (notifier:INotifyPropertyChanged, trigger:Action<_,_>) =
        let propertyName =
            try
                let props = TypeDescriptor.GetProperties (notifier.GetType ())
                new StackTrace (1) |> fun st -> st.GetFrames () |> Seq.take 3 //Should never be more than 3 deep
                |> Seq.pick (fun f -> 
                    let m = f.GetMethod ()
                    let pName = m.Name |> String.skip 4
                    (props.[pName] <> null) |> Bool.toOption pName)
            with e -> invalidOp ("OnPropertyChanged can only be called from within a property!")

        trigger.Invoke (notifier, new PropertyChangedEventArgs (propertyName))

    type INotifyPropertyChanged with
        member this.OnPropertyChanged (trigger) =
            OnPropertyChanged (this, new Action<_,_> (fun a b -> trigger(a, b)))